
#include "Assert_t.hh"
#include <QtTest/QtTest>
#include "Assert.hpp"
#include "Ex.hh"
#include "Debug.hh"

using namespace std;
using namespace TC;



// TC_ASSERT_COMPILE tests
void Assert_t::assert_compile()
{
  // This should always compile
  TC_ASSERT_COMPILE(true);
  TC_ASSERT_COMPILE(1+1);
  // This should always fail to compile
  //TC_ASSERT_COMPILE(1-1);

  QVERIFY(true);
}


// TC_ASSERT_SIMPLE tests
void Assert_t::assert_simple()
{
  // Positive test, shouldn't throw exception
  TC_ASSERT_SIMPLE(true);
  // Negative test, should throw exception
  try {
    TC_ASSERT_SIMPLE(false);
    // Control shouldn't come here
    QVERIFY(false);
  }
  catch(const Ex&) {
    // Success
  }
  catch(...) {
    throw; // Failure
  }

  QVERIFY(true);
}


// TC_ASSERT_LEVEL tests
void Assert_t::assert_level()
{
  // Set assertion acceptance level to some level
  AssertionLevel::Set(e_ALInvariant);
  // Positive test, shouldn't throw exception
  TC_ASSERT_LEVEL(e_ALMax,true || "TC_ASSERT_LEVEL positive test");
  // Negative test, should throw exception
  try {
    TC_ASSERT_LEVEL(e_ALBasic, false && "TC_ASSERT_LEVEL negative test");
    QVERIFY(false);
  }
  catch(const Ex&) {
    // Success
  }
  catch(...) {
    throw; // Failure
  }
  
  QVERIFY(true);
}


// TC_ASSERT_CONTEXT tests
void Assert_t::assert_context()
{
  // Positive test, shouldn't throw exception
  TC_ASSERT_CONTEXT(true);
  // Disable assertions completely
  AssertionLevel::Set(e_ALOff);
  // This shouldn't throw exception since 
  // the AssertionLevel < e_ALBasic
  TC_ASSERT_CONTEXT(false);
  // Revert back to maximum assertion acceptance
  AssertionLevel::Set(e_ALMax);
  // Negative test, should throw exception
  try {
    TC_ASSERT_CONTEXT(false);
    QVERIFY(false && "TC_ASSERT_CONTEXT negative test");
  } 
  catch(const Ex&) { 
    // Success 
  }
  catch(...) {
    throw; // Failure;
  }

  QVERIFY(true);
}


// TC_ASSERT_SMART tests
void Assert_t::assert_smart()
{
  // Positive tests, shouldn't throw any exception
  TC_ASSERT_SMART(true);
  TC_ASSERT_SMART(2==1+1);
  try {
    bool b1 = true;
    bool b2 = true;
    bool b3 = false;
    // Negative test, should throw exception
    TC_ASSERT_SMART(b1 && b2 && b3)(b1)(b2)(b3);
    QVERIFY(false);
  }
  catch(const Ex&) {
    // Success
  }
  catch(...) {
    throw; // Failure;
  }

  QVERIFY(true);
}


// TC_VERIFY tests
void Assert_t::assert_verify()
{
  // Positive tests, shouldn't throw exception
  int i = 1;
  TC_VERIFY(i--);
  TC_ASSERT(i==0);
  // Negative test,  should throw exception
  try {
    TC_VERIFY(i--);
    QVERIFY(false && "TC_VERIFY negative test");
  }
  catch(const Ex&) {
    // Success
  }
  catch(...) {
    throw; // Failure
  }

  // Final expectation
  TC_ASSERT(i == -1);
  
  QVERIFY(true);
}
  
